/**
* @program: Go
*
* @description:api入口
*
* @author: Mr.chen
*
* @create: 2020-08-19 15:01
**/
package main
import (
	"ydd-im/config"
	"ydd-im/service/api/define"
	"ydd-im/service/api/models"
	"ydd-im/service/api/pkg/etcd"
	"ydd-im/service/api/router"
	"ydd-im/service/api/services/wsservice/rpc"
	"ydd-im/service/api/tools/util"
	"ydd-im/util/logger"
	"context"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)
func main() {
	// init logger
	if err := logger.InitLogger(config.GetZapLog()); err != nil {
		log.Fatalf("init logger failed, err:%v\n", err)
		return
	}
	port :=getPort()
	etcdHost := config.GetApiConfig().ApiEtcd.Host
	if len(etcdHost) > 0 {
		define.EtcdEndpoints = make([]string, 0)
		define.EtcdEndpoints = append(define.EtcdEndpoints, etcdHost)
	}
	//初始化RPC服务
	initRPCServer(port)
	//记录本机内网IP地址
	define.LocalHost = util.GetIntranetIp()
	//将服务器地址、端口注册到etcd中
	registerServer()
	// 注册数据库
	models.InitDb()
	//zap.L().Debug("this is hello func", zap.Int("age", 1))
	r := router.Register()
	// 性能分析 - 正式环境不要使用！！！
	//pprof.Register(r)
	srv := &http.Server{
		Addr         : ":"+port,
		Handler      : r,
		ReadTimeout  : config.AppReadTimeout * time.Second,
		WriteTimeout : config.AppWriteTimeout * time.Second,
	}
	fmt.Println("|-----------------------------------|")
	fmt.Println("|          ydd-im              |")
	fmt.Println("|          author Mr.chen           |")
	fmt.Println("|-----------------------------------|")
	fmt.Println("|  Go Http Server Start Successful  |")
	fmt.Println("|    Port" + port + "     Pid:" + fmt.Sprintf("%d", os.Getpid()) + "        |")
	fmt.Println("|-----------------------------------|")
	fmt.Println("")
	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
		//err =r.Run(config.GetService().Port)
		//if err != nil  && err != http.ErrServerClosed {
		//	log.Fatalf("web server init err: %v", err)
		//}
	}()
	//for  {
	//	fmt.Println(len(define.ServerList))
	//	time.Sleep(2*time.Second)
	//}
	// 等待中断信号以优雅地关闭服务器（设置 5 秒的超时时间）
	signalChan := make(chan os.Signal)
	signal.Notify(signalChan, os.Interrupt,syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	sig := <-signalChan
	log.Println("Get Signal:", sig)
	log.Println("Shutdown Server ...")
	// 优雅的关机
	ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}
func initRPCServer(port string) {
	//如果是集群，则启用RPC进行通讯
	if util.IsCluster() {
		//初始化RPC服务
		rpcPort := util.GenRpcPort(port)
		rpc.InitGRpcServer(rpcPort)
		fmt.Printf("启动RPC，端口号：%s\n", rpcPort)
	}
}

//ETCD注册发现服务
func registerServer() {
	if util.IsCluster() {
		//注册租约

		ser, err := etcd.NewServiceReg(define.EtcdEndpoints, 5)
		if err != nil {
			panic(err)
		}

		hostPort := net.JoinHostPort(define.LocalHost, define.RPCPort)
		//fmt.Println(define.EtcdEndpoints,define.LocalHost,define.RPCPort,define.ETCD_SERVER_LIST+hostPort,hostPort)
		//添加key
		err = ser.PutService(define.ETCD_SERVER_LIST+hostPort, hostPort)
		if err != nil {
			panic(err)
		}
		cli, err := etcd.NewClientDis(define.EtcdEndpoints)
		if err != nil {
			panic(err)
		}
		_, err = cli.GetService(define.ETCD_SERVER_LIST)
		if err != nil {
			panic(err)
		}
		// 获取账号微服务启用的远程rpc地址，监听key值
		_, err = cli.GetService(define.ETCD_SERVER_Account_LIST)
		if err != nil {
			panic(err)
		}
		// 获取群微服务启用的远程rpc地址，监听key值
		_, err = cli.GetService(define.ETCD_SERVER_Group_LIST)
		if err != nil {
			panic(err)
		}
	}
}
// 自定义端口
func getPort() string {
	port := config.GetService().Port
	args := os.Args //获取用户输入的所有参数
	if len(args) >= 2 && len(args[1]) != 0 {
		port = args[1]
	}
	define.Port = port
	return port
}

